local error = error
local print = print
local pairs = pairs
local ipairs = ipairs
local pcall = pcall
local tostring = tostring
local format = string.format
local open = io.open
local log = log
local sort = table.sort

local G = _G
local parse

module("cvar")

local NIL = {}
local cvars = {}
local defaults = {}
local names = {}

function Initialize()
	parse = G.wtf.Parse
	parse("wtf/config.wtf")
end

function Register(name, value)
	local lname = name:lower()
	if defaults[lname] then
		error(format("CVAR already registered: %s", name))
	end
	defaults[lname] = value or NIL
	names[lname] = name
end

function Get(name)
	local lname = name:lower()
	local rname = names[lname]
	if not rname then
		error(format("Invalid cvar name in Get() : %s", name))
	end
	local v = cvars[lname] or defaults[lname]
	if v ~= NIL then return v end
end

function GetDefault(name)
	local lname = name:lower()
	local rname = names[lname]
	if not rname then
		error(format("Invalid cvar name in GetDefault() : %s", name))
	end
	local v = defaults[lname]
	if v ~= NIL then return v end
end

function Set(name, value, script)
	local lname = name:lower()
	local rname = names[lname]
	if not rname then
		error(format("Invalid cvar name in Set() : %s", name))
	end
	cvars[lname] = value and tostring(value)
end

function Load()
	pcall(parse, "save/config.wtf")
end

function Save()
	local f = open("save/config.wtf", "w")
	local temp = {}
	for name in pairs(cvars) do
		temp[#temp + 1] = name
	end
	sort(temp)

	for _, name in ipairs(temp) do
		local value = cvars[name]
		if value ~= defaults[name] then
			if value == NIL then value = "nil" end
			f:write(format("SET %s %q\n", names[name], value))
		end
	end
	f:close()
end
